/*
 * role_menu表操作，没有对应的实体，只需要获取菜单id和菜单路径即可
 * */
package com.xtedu.examproject.util;

import com.xtedu.examproject.entity.Menu;
import com.xtedu.examproject.entity.MenuPath;
import com.xtedu.examproject.entity.User;
import com.xtedu.examproject.service.MenuService;
import com.xtedu.examproject.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class NavManagementUtil {

    private static final Logger log = LoggerFactory.getLogger(NavManagementUtil.class);
    private MenuService menuService;

    public NavManagementUtil() {
        menuService = new MenuService();
    }

    /*
     * @描述：获取全部的导航链接
     * @参数：menuPaths: 菜单路径里的所有信息,menus : 菜单信息
     * 返回值：List<MenuPath> 获取到的导航链接
     * */
    public List<MenuPath> getNavLink(List<MenuPath> menuPaths, List<Menu> menus) {
        return menuPaths;
    }

    /*
     *功能：导航链接显示
     * 参数：menuPaths: 菜单路径里的所有信息,menus : 菜单信息
     * 返回值：List<MenuPath> 过滤掉菜单信息后的菜单路径信息
     * */
    public List<MenuPath> getFilterNavLink(List<MenuPath> menuPaths, List<Menu> menus) {
        //过滤掉相同id的menuPath
        return menuPaths.stream().filter(menuPath -> {
            for (Menu menu : menus) {
                if (menu.getId() == menuPath.getId()) {
                    return false;
                }
            }
            return true;
        }).toList();
    }

    /*
    * 添加菜单功能
    *
    * 参数：roleId: 角色id;
    * menuName: 菜单名称;
    menuId:菜单id;
    menuPath: 菜单路径,
    menuIcon: 菜单图标,
    * menuParentId: 菜单父级id
    *
    *同时添加role_menu表数据和menu_items表数据,菜单添加成功返回true,否则返回false
    *
    * 返回值：boolean
    * 操作步骤：
    *
    *1. 插入menu_items表数据
    * 2. 插入role_menu表数据（根据该表特点）
    *
    *     */
    public boolean addNewMenu(int roleId, String menuName, int menuId, String menuPath, String menuIcon, int menuParentId) throws Exception {


        //管理员功能插入role_menu表数据
        int adminId = new UserService().findUserByUsername("admin").getRoleId();//获取管理员id
        boolean insertMenuItemsResult = false;
        //插入menu_items是否成功
        Menu menu = new Menu(menuId, menuParentId, menuName, menuPath, menuIcon, true);
        int insertMenuItemsNum = new MenuService().insert(menu);//插入menu_items表数据
        insertRoleMenu(roleId, menuName, menuPath);//插入用户role_menu表数据
        insertRoleMenu(adminId, menuName, menuPath);//插入管理员role_menu表数据
        insertMenuItemsResult = insertMenuItemsNum > 0;
        return insertMenuItemsResult;
    }

    public boolean insertRoleMenu(int roleId, String menuName, String menuPath) throws Exception {

        int menuId = new MenuService().findIdByNameAndPath(menuName, menuPath);
        boolean result = false;
        String sql = "INSERT INTO role_menu (role_id, menu_id, state) VALUES (?, ?, ?) " +
                "ON DUPLICATE KEY UPDATE state = VALUES(state)";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, roleId);
            ps.setInt(2, menuId);
            ps.setInt(3, 1);
            result = ps.executeUpdate() > 0;//返回值大于0则成功
        } catch (SQLException e) {
            log.error("role_menu表数据插入失败", e);
            log.error("role_menu表插入用户数据插入失败", e);
        }
        return result;
    }

    /*
     * @描述：删除菜单功能
     * @参数：menuId: 菜单id(role_menu)
     * 返回值：boolean
     * */
    public boolean delRoleMenu(int menuId) throws Exception {
        boolean result = false;
        String sql = "DELETE FROM role_menu WHERE menu_id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, menuId);
            result = ps.executeUpdate() > 0;//返回值大于0则成功
        } catch (SQLException e) {
            log.error("role_menu表删除用户数据失败", e);
        }
        return result;
    }

    /*
     * @描述：更新session中的菜单数据
     * @参数：request: 请求对象
     * 返回值：void
     * */
    public User updateSessionMenu(HttpServletRequest request) {
        try {
            User user = (User) request.getSession().getAttribute("user");
            if (user != null) {
                List<Menu> updatedMenus = menuService.findMenusByRoleId(user.getRoleId());//获取更新后的菜单数据
                List<Menu> menusTree = MenuTreeBuilder.buildMenuTree(updatedMenus);//构建菜单树
                user.setMenus(menusTree);//设置菜单数据
                request.getSession().setAttribute("user", user);//更新session中的菜单数据

                System.out.println("Session中的菜单数据已更新，当前数量: " + updatedMenus.size());
            } else {
                System.err.println("用户未登录，无法更新session菜单数据");
            }
        } catch (Exception e) {
            System.err.println("更新session菜单数据失败: " + e.getMessage());
            log.error("更新session菜单数据失败", e);
        }
        return (User) request.getSession().getAttribute("user");
    }

    /*
     * @描述：通过menu_id获取role_menu表数据
     * @参数：menuId: 菜单id
     * @返回值：List<RoleMenu>
     * */
    public List<Integer> getRoleMenuByMenuId(int menuId) throws Exception {
        List<Integer> roleIds = new ArrayList<>();
        String sql = "SELECT role_id FROM role_menu WHERE menu_id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, menuId);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                roleIds.add(rs.getInt("role_id"));
            }
        } catch (SQLException e) {
            log.error("获取role_menu表数据失败", e);
        }
        //过滤掉管理员的角色id (硬编码，通过查询user表的admin来动态获得对应的roleId)
        //添加越界检测,默认返回列表为0的角色id
        return !roleIds.stream().filter(roleId -> roleId != 3).toList().isEmpty() ? roleIds.stream().filter(roleId -> roleId != 3).toList() : List.of(0);
    }
}

